﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Timeline.Beans;
using Timeline.Inis;
using Windows.ApplicationModel;
using Windows.System;
using Windows.System.Profile;
using Windows.System.UserProfile;

namespace Timeline.Utils {
    public class Api {
        public static async Task StatsAsync(Ini ini, int dosageApp, int dosageApi) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return;
            }
            const string URL_API = "https://api.nguaduot.cn/appstats";
            Windows.Foundation.Size resolution = SysUtil.GetMonitorPixels(false); // 分辨率
            double scaleFactor = SysUtil.GetMonitorScale(); // 缩放因子
            double diagonalInch = SysUtil.GetMonitorDiagonal(); // 屏幕物理大小（吋）
            string screen = string.Format("{0}x{1},{2},{3}", (int)resolution.Width, (int)resolution.Height,
                scaleFactor.ToString("0.00"), diagonalInch.ToString("0.0"));
            StatsApiReq req = new StatsApiReq {
                App = Package.Current.DisplayName, // 不会随语言改变
                Package = Package.Current.Id.FamilyName,
                Version = SysUtil.GetPkgVer(false),
                Architecture = Package.Current.Id.Architecture.ToString(),
                Api = ini?.ToString(),
                DosageApp = dosageApp,
                DosageApi = dosageApi,
                Pc = SysUtil.GetPcType(),
                Os = AnalyticsInfo.VersionInfo.DeviceFamily,
                OsVersion = SysUtil.GetOsVer(),
                Screen = screen,
                Device = SysUtil.GetDevice(),
                DeviceName = SysUtil.GetDeviceName(),
                Region = GlobalizationPreferences.HomeGeographicRegion
            };
            try {
                HttpClient client = new HttpClient();
                //content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Post, URL_API);
                msgReq.Headers.Add("Timeline-Device", SysUtil.GetDeviceId());
                msgReq.Content = new StringContent(JsonConvert.SerializeObject(req), Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("StatsAsync() " + jsonData.Trim());
            } catch (Exception e) {
                LogUtil.E("StatsAsync() " + e.Message);
            }
        }

        public static async Task RankAsync(Ini ini, Meta meta, string action, string target = null) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return;
            }
            LogUtil.D("RankAsync() " + action);
            const string URL_API = "https://api.nguaduot.cn/appstats/rank/v2";
            string providerFix = !string.IsNullOrEmpty(meta?.IdGlobalPrefix) ? meta?.IdGlobalPrefix : ini?.Provider;
            string imgIdFix = !string.IsNullOrEmpty(meta?.IdGlobalSuffix) ? meta?.IdGlobalSuffix : meta?.Id;
            RankApiReq req = new RankApiReq {
                Provider = providerFix,
                Id = imgIdFix,
                Url = meta?.Uhd,
                Action = action,
                Target = target,
                Version = SysUtil.GetPkgVer(false),
                Region = GlobalizationPreferences.HomeGeographicRegion
            };
            try {
                HttpClient client = new HttpClient();
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Post, URL_API);
                msgReq.Headers.Add("Timeline-User", ini?.UserEncoded());
                msgReq.Headers.Add("Timeline-Pwd", ini?.PwdEncrypted());
                msgReq.Headers.Add("Timeline-Device", SysUtil.GetDeviceId());
                msgReq.Headers.Add("Timeline-Client", ini?.Client ?? "");
                msgReq.Content = new StringContent(JsonConvert.SerializeObject(req), Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("RankAsync() " + jsonData.Trim());
            } catch (Exception e) {
                LogUtil.E("RankAsync() " + e.Message);
            }
        }

        public static async Task UndoRankAsync(Ini ini, Meta meta, string[] actions) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return;
            }
            LogUtil.D("UndoRankAsync() " + string.Join(" ", actions));
            const string URL_API = "https://api.nguaduot.cn/appstats/rank/undo";
            string providerFix = !string.IsNullOrEmpty(meta?.IdGlobalPrefix) ? meta?.IdGlobalPrefix : ini?.Provider;
            string imgIdFix = !string.IsNullOrEmpty(meta?.IdGlobalSuffix) ? meta?.IdGlobalSuffix : meta?.Id;
            UndoRankApiReq req = new UndoRankApiReq {
                Provider = providerFix,
                Id = imgIdFix,
                Actions = new List<string>(actions)
            };
            try {
                HttpClient client = new HttpClient();
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Post, URL_API);
                msgReq.Headers.Add("Timeline-User", ini?.User ?? "");
                msgReq.Headers.Add("Timeline-Pwd", ini?.Pwd ?? "");
                msgReq.Headers.Add("Timeline-Device", SysUtil.GetDeviceId());
                msgReq.Headers.Add("Timeline-Client", ini?.Client ?? "");
                msgReq.Content = new StringContent(JsonConvert.SerializeObject(req), Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("UndoRankAsync() " + jsonData.Trim());
            } catch (Exception e) {
                LogUtil.E("UndoRankAsync() " + e.Message);
            }
        }

        public static async Task<ReleaseApiData> VersionAsync() {
            ReleaseApiData res = new ReleaseApiData();
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return res;
            }
            const string URL_VERSION = "https://api.nguaduot.cn/appstats/version/v2?pkg={0}";
            string urlApi = string.Format(URL_VERSION, Uri.EscapeUriString(Package.Current.Id.FamilyName));
            try {
                HttpClient client = new HttpClient();
                string jsonData = await client.GetStringAsync(urlApi);
                //LogUtil.D("VersionAsync() " + jsonData.Trim());
                ReleaseApi api = JsonConvert.DeserializeObject<ReleaseApi>(jsonData);
                if (api.Status != 1) {
                    return res;
                }
                return api.Data;
            } catch (Exception e) {
                LogUtil.E("VersionAsync() " + e.Message);
            }
            return res;
        }

        public static async Task<GlitterApiData> GlitterAsync(string clientKey) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return null;
            }
            //const string URL_GLITETR = "https://glitter.timeline.ink/api/user?json=1&lines=1&general=0&user=wheat";
            const string URL_GLITETR = "https://glitter.timeline.ink/api/v1?json=1&lines=1&general=0";
            try {
                HttpClient client = new HttpClient();
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Get, URL_GLITETR);
                msgReq.Headers.Add("Timeline-Client", clientKey ?? "");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                //LogUtil.D("GlitterAsync() " + jsonData.Trim());
                GlitterApi api = JsonConvert.DeserializeObject<GlitterApi>(jsonData);
                if (api.Status != 1) {
                    return null;
                }
                return api.Data[0];
            } catch (Exception e) {
                LogUtil.E("GlitterAsync() " + e.Message);
            }
            return null;
        }

        public static async Task CrashAsync(Exception e) {
            if (e == null || !NetworkInterface.GetIsNetworkAvailable()) {
                return;
            }
            const string URL_API = "https://api.nguaduot.cn/appstats/crash";
            CrashApiReq req = new CrashApiReq {
                App = Package.Current.DisplayName, // 不会随语言改变
                Package = Package.Current.Id.FamilyName,
                Version = SysUtil.GetPkgVer(false),
                Os = AnalyticsInfo.VersionInfo.DeviceFamily,
                OsVersion = SysUtil.GetOsVer(),
                Device = SysUtil.GetDevice(),
                DeviceId = SysUtil.GetDeviceId(),
                Exception = e.ToString()
            };
            try {
                HttpClient client = new HttpClient();
                HttpContent content = new StringContent(JsonConvert.SerializeObject(req),
                    Encoding.UTF8, "application/json");
                //content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                HttpResponseMessage response = await client.PostAsync(URL_API, content);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("Crash() " + jsonData.Trim());
            } catch (Exception ex) {
                LogUtil.E("Crash() " + ex.Message);
            }
        }

        public static async Task<List<CateApiData>> CateAsync(string urlApi) {
            List<CateApiData> data = new List<CateApiData>();
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return data;
            }
            if (string.IsNullOrEmpty(urlApi)) {
                return data;
            }
            try {
                HttpClient client = new HttpClient();
                HttpResponseMessage res = await client.GetAsync(urlApi);
                string jsonData = await res.Content.ReadAsStringAsync();
                LogUtil.D("CateAsync(): " + jsonData.Trim());
                CateApi api = JsonConvert.DeserializeObject<CateApi>(jsonData);
                if (api.Data != null) {
                    data = api.Data;
                    data.Sort((a, b) => b.Score.CompareTo(a.Score));
                }
            } catch (Exception e) {
                LogUtil.E("CateAsync() " + e.Message);
            }
            return data;
        }

        public static async Task<AccountApiData> R22AuthAsync(string comment, string user, string pwd, string clientKey) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return null;
            }
            const string URL_API = "https://api.nguaduot.cn/appstats/apply/r22";
            R22AuthApiReq req = new R22AuthApiReq {
                Comment = comment
            };
            try {
                HttpClient client = new HttpClient();
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Post, URL_API);
                msgReq.Headers.Add("Timeline-User", TextUtil.Encode(user));
                msgReq.Headers.Add("Timeline-Pwd", TextUtil.Md5(pwd));
                msgReq.Headers.Add("Timeline-Device", SysUtil.GetDeviceId());
                msgReq.Headers.Add("Timeline-Client", clientKey ?? "");
                msgReq.Content = new StringContent(JsonConvert.SerializeObject(req), Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("R22AuthAsync(): " + jsonData.Trim());
                R22AuthApi api = JsonConvert.DeserializeObject<R22AuthApi>(jsonData);
                if (api.Data && api.Auth != null && api.Auth.Status == 1) {
                    return api.Auth.Data;
                }
                return null;
            } catch (Exception e) {
                LogUtil.E("R22AuthAsync() " + e.Message);
            }
            return null;
        }

        public static async Task<AccountApiData> CheckAccountAsync(bool checkChat, bool checkDown, string user, string pwd, string clientKey) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return null;
            }
            if (string.IsNullOrEmpty(user)) {
                return null;
            }
            LogUtil.D("CheckAccountAsync()");
            const string URL_API = "https://api.nguaduot.cn/appstats/account";
            AccountApiReq req = new AccountApiReq {
                Chat = checkChat,
                Download = checkDown
            };
            try {
                HttpClient client = new HttpClient();
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Post, URL_API);
                msgReq.Headers.Add("Timeline-User", TextUtil.Encode(user));
                msgReq.Headers.Add("Timeline-Pwd", TextUtil.Md5(pwd));
                msgReq.Headers.Add("Timeline-Device", SysUtil.GetDeviceId());
                msgReq.Headers.Add("Timeline-Client", clientKey ?? "");
                msgReq.Content = new StringContent(JsonConvert.SerializeObject(req), Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("CheckAccountAsync() " + jsonData.Trim());
                AccountApi api = JsonConvert.DeserializeObject<AccountApi>(jsonData);
                if (api.Status != 1) {
                    return null;
                }
                return api.Data;
            } catch (Exception e) {
                LogUtil.E("CheckAccountAsync() " + e.Message);
            }
            return null;
        }

        public static async Task<bool> BindDeviceAsync(string user, string pwd, string clientKey) {
            if (!NetworkInterface.GetIsNetworkAvailable()) {
                return false;
            }
            LogUtil.D("BindDeviceAsync()");
            const string URL_API = "https://api.nguaduot.cn/appstats/bind";
            try {
                HttpClient client = new HttpClient();
                HttpRequestMessage msgReq = new HttpRequestMessage(HttpMethod.Get, URL_API);
                msgReq.Headers.Add("Timeline-User", TextUtil.Encode(user));
                msgReq.Headers.Add("Timeline-Pwd", TextUtil.Md5(pwd));
                msgReq.Headers.Add("Timeline-Device", SysUtil.GetDeviceId());
                msgReq.Headers.Add("Timeline-Client", clientKey ?? "");
                HttpResponseMessage response = await client.SendAsync(msgReq);
                _ = response.EnsureSuccessStatusCode();
                string jsonData = await response.Content.ReadAsStringAsync();
                LogUtil.D("BindDeviceAsync() " + jsonData.Trim());
                AccountBindApi api = JsonConvert.DeserializeObject<AccountBindApi>(jsonData);
                return api.Status == 1 && api.Data;
            } catch (Exception e) {
                LogUtil.E("BindDeviceAsync() " + e.Message);
            }
            return false;
        }
    }
}
